#ifndef _COLOR_FORMULA_H_
#define _COLOR_FORMULA_H_

#include <stdint.h>
#include <stdbool.h>
#include <appConfig.h>

#define COLOR_COEFFICIENT_POS    (16)
#define COLOR_COEFFICIENT        (1ul << COLOR_COEFFICIENT_POS)

#define COLOR_MUX_POS            (14)
#define COLOR_MUX                (1ul << COLOR_MUX_POS)

#define PARAM_VALID              (0x55AA55AA)





typedef enum{
  LED_RED = 0,
  LED_GREEN,
  LED_BLUE
}LedType_t;


typedef struct{ 
    int16_t temperature; //0.1C
    int16_t deltaVoltPN; //mV
    int16_t efficiency;  //0.1%
}TempCompensation_t;


typedef struct{ 
    uint16_t x;         //0-65535
    uint16_t y;         //0-65535
}Coordinate_t;


typedef struct{ 
    uint16_t x;         //0-65535
    uint16_t y;         //0-65535
    uint16_t intensity;
}CoordinateParam_t;

typedef struct{ 
    CoordinateParam_t        red;
    CoordinateParam_t        green;
    CoordinateParam_t        blue;
}LedCoordinate_t;
  
typedef struct{ 
    uint32_t X;         //x COLOR_MUX
    uint32_t Y;         //x COLOR_MUX
    uint32_t Z;         //x COLOR_MUX
}CoordinateXYZ_t;


typedef struct{ 
    Coordinate_t        color[3];
    CoordinateXYZ_t     colorXYZ[3];
    uint16_t            ratio[3];//0-COLOR_MUX
    uint16_t            maxTypicalIntensity[3];//0-65535 @25C
    uint16_t            maxPWM[3];//0-65535
    uint16_t            ledTypicalPNVolt[3];   // @25C
}LedParam_t;

typedef struct{
    uint32_t                    valid;
    LedParam_t                  param[8];
}LedPhyParam_t;


typedef struct{ 
    uint16_t            maxIntensity[3];//0-65535
    uint16_t            maxPWM[3];//0-65535
}LedRTParam_t;

typedef struct{ 
    LedRTParam_t        param[8];
}LedRunTimeParam_t;


typedef struct{
    uint16_t red;       //0-65535
    uint16_t green;     //0-65535
    uint16_t blue;      //0-65535
    int16_t result;    // 0: OK, other: NG
}LedTarget_t;

typedef struct{ 
    int32_t x;//0-65535
    int32_t y;//0-65535
}CPoint_t;

typedef struct{ 
    int64_t Yr;//0-COLOR_MUX
    int64_t Yg;//0-COLOR_MUX
    int64_t Yb;//0-COLOR_MUX
}CPointY_t;

typedef enum{ 
    MIXING_INVALID_PARAM = 0,
    MIXING_ONE_COLOR_RED,
    MIXING_ONE_COLOR_GREEN,
    MIXING_ONE_COLOR_BLUE,
    MIXING_TWO_COLOR_RED_GREEN,
    MIXING_TWO_COLOR_GREEN_BLUE,
    MIXING_TWO_COLOR_BLUE_RED,
    MIXING_THREE_COLOR,
}CMixingType_t;


/* @brief
 * for white point param calculating
 */
/*
 * Set Led physical param : x,y coordinate, intensity in Lumin (for example)
 *  @param [in] type: LED type
 *  @param [in] temperature: current temperature -400-1250 in 0.1C
 *  @param [in] coordinate: Led coordinate for example:P(0.3333,0.3333) = P(21845,21845);
 *  @param [in] intensity: 0-65535 in Lumin (for example)
 *  @return 0
 */
//int8_t CFL_SetLedPhyParams(LedType_t type, int16_t temperature, Coordinate_t *coordinate, uint16_t intensity);
int8_t CFL_SetLedPhyParams(int16_t temperature, LedNumber_t ledNo, LedCoordinate_t *coordinate);
/*
 * Set Led PN volt @specifical temperature in mV
 *  @param [in] temperature: current temperature -400-1250 in 0.1C
 *  @param [in] volt_R: Red Led PN volt (mV);
 *  @param [in] volt_G: Green Led PN volt (mV);
 *  @param [in] volt_B: Blue Led PN volt (mV);
 *  @return 0
 */
//int8_t CFL_SetLedPNVolts(int16_t temperature, uint16_t volt_R, uint16_t volt_G, uint16_t volt_B);
int8_t CFL_SetLedPNVolts(int16_t temperature, LedNumber_t ledNo, uint16_t volt_R, uint16_t volt_G, uint16_t volt_B);
/*
 * Get Led PN volt @25C temperature in mV
 *  @param [out] volt_R: Red Led PN volt (mV);
 *  @param [out] volt_G: Green Led PN volt (mV);
 *  @param [out] volt_B: Blue Led PN volt (mV);
 *  @return 0
 */
//int8_t CFL_GetLedPNVolts(uint16_t *volt_R, uint16_t *volt_G, uint16_t *volt_B);
int8_t CFL_GetLedPNVolts(LedNumber_t ledNo, uint16_t *volt_R, uint16_t *volt_G, uint16_t *volt_B);
/*
 *  whitePoint intensity calculating
 *  @param [in] whitePoint: white point coordinatefor example:P(0.3333,0.3333) = P(21845,21845);
 *  @return 0
 */
//int8_t CFL_DoWhitePointCalculating(Coordinate_t whitePoint);
int8_t CFL_DoWhitePointCalculating(LedNumber_t ledNo,Coordinate_t whitePoint);
/*
 * Set Led PWM parameters for calculating max intensity of R,G,B
 *  @param [in] maxPWM_R: at White Point
 *  @param [in] maxPWM_G: at White Point
 *  @param [in] maxPWM_B: at White Point
 *  @return 0
 */
//int8_t CFL_SetWhitePointPWMs(uint16_t maxPWM_R,uint16_t maxPWM_G,uint16_t maxPWM_B);
int8_t CFL_SetWhitePointPWMs(LedNumber_t ledNo,uint16_t maxPWM_R,uint16_t maxPWM_G,uint16_t maxPWM_B);
/*
 * Get Led max PWM parameters of R,G,B
 *  @param [out] maxPWM_R: at White Point
 *  @param [out] maxPWM_G: at White Point
 *  @param [out] maxPWM_B: at White Point
 *  @return 0
 */
//int8_t CFL_GetWhitePointPWMs(uint16_t *maxPWM_R,uint16_t *maxPWM_G,uint16_t *maxPWM_B);
int8_t CFL_GetWhitePointPWMs(LedNumber_t ledNo,uint16_t *maxPWM_R,uint16_t *maxPWM_G,uint16_t *maxPWM_B);
/*
 * Save color Parameters
 *  @return 0,OK,others:NG
 */
int8_t CFL_StorageColorParams(void);


/*
 * restore color Parameters
 *  @return 0,OK,others:NG
 */
int8_t CFL_RestoreColorParams(void);






















/*
 *  Set xyY output  for example: P(x,y) = (0.33333,0.33333) x = 0.33333*65536 = 21845, y =  0.33333*65536 = 21845
 *  @param [in] x: 0-65535
 *  @param [in] y: 0-65535
 *  @param [in] Y: 0-65535
 *  @return r,g,b DutyCycle,
 */
//LedTarget_t CFL_XYYToDutyCycle(uint16_t x, uint16_t y, uint16_t Y);
LedTarget_t CFL_XYYToDutyCycle(LedNumber_t ledNo,uint16_t xPoint, uint16_t yPoint, uint16_t Y);
/*
 *  Set hue saturation level output 
 *  @param [in] saturation: 0-255
 *  @param [in] level: 0-65535
 *  @return r,g,b DutyCycle
 */
//LedTarget_t CFL_HSLToDutyCycle(uint16_t hue, uint8_t saturation, uint16_t level);
LedTarget_t CFL_HSLToDutyCycle(LedNumber_t ledNo,uint16_t hue, uint8_t saturation, uint16_t level);
/*
 *  Set RGB output 
 *  @param [in] red: 0-255
 *  @param [in] green: 0-255
 *  @param [in] blue: 0-255
 *  @param [in] level: 0-65535
 *  @return r,g,b DutyCycle
 */
//LedTarget_t CFL_RGBLToDutyCycle(uint8_t red, uint8_t green, uint8_t blue,uint16_t level);
LedTarget_t CFL_RGBLToDutyCycle(LedNumber_t ledNo,uint8_t r, uint8_t g, uint8_t b,uint16_t level);
/*
 *  Set RGB output 
 *  @param [in] red: 0-255
 *  @param [in] green: 0-255
 *  @param [in] blue: 0-255
 *  @return r,g,b DutyCycle
 */
//LedTarget_t CFL_RGBToDutyCycle(uint8_t red, uint8_t green, uint8_t blue);
LedTarget_t CFL_RGBToDutyCycle(LedNumber_t ledNo,uint8_t red, uint8_t green, uint8_t blue);
/*
 *  Get RGB channel max pwm value
 *  @param [in] Led type
 *  @return r/g/b DutyCycle
 */
//uint16_t CFL_GetRuntimeLedMaxPWM(LedType_t type);
uint16_t CFL_GetRuntimeLedMaxPWM(LedNumber_t ledNo,LedType_t type);
/*
 *  Get run time max phycial intensity
 *  @param [in] Led type
 *  @return max phycial intensity of Led type
 */
//uint16_t CFL_GetRunTimePhyMaxIntensity(LedType_t type);
uint16_t CFL_GetRunTimePhyMaxIntensity(LedNumber_t ledNo,LedType_t type);
/*
 *  do temperature compesation based on current temperature
 *  @param [in] temperature: in 0.1C
 *  @return none
 */
//void CFL_DoTempCompensating(int16_t temperature);
void CFL_DoTempCompensating(int16_t temperature,LedNumber_t ledNo);
#endif